package com.example.social.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.social.common.BusinessException;
import com.example.social.dto.UserDTO;
import com.example.social.entity.Friendship;
import com.example.social.entity.User;
import com.example.social.mapper.FriendshipMapper;
import com.example.social.mapper.UserMapper;
import com.example.social.service.FriendshipService;
import com.example.social.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class FriendshipServiceImpl extends ServiceImpl<FriendshipMapper, Friendship> implements FriendshipService {

    private final UserService userService;
    private final UserMapper userMapper;

    @Override
    public Map<String, List<UserDTO>> getFriendList() {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User currentUser = userService.getByUsername(username);

        Map<String, List<UserDTO>> result = new HashMap<>();

        // 查询关注列表
        LambdaQueryWrapper<Friendship> followingWrapper = new LambdaQueryWrapper<>();
        followingWrapper.eq(Friendship::getUserId, currentUser.getId());
        List<Friendship> followings = list(followingWrapper);

        List<UserDTO> friends = followings.stream()
                .map(friendship -> {
                    User friend = userMapper.selectById(friendship.getFriendId());
                    return userService.convertToDTO(friend);
                })
                .collect(Collectors.toList());

        // 查询粉丝列表
        LambdaQueryWrapper<Friendship> followerWrapper = new LambdaQueryWrapper<>();
        followerWrapper.eq(Friendship::getFriendId, currentUser.getId());
        List<Friendship> followers = list(followerWrapper);

        List<UserDTO> requests = followers.stream()
                .map(follower -> {
                    User fan = userMapper.selectById(follower.getUserId());
                    return userService.convertToDTO(fan);
                })
                .collect(Collectors.toList());

        result.put("friends", friends);
        result.put("requests", requests);
        return result;
    }

    @Override
    @Transactional
    public void addFriend(Long userId) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User currentUser = userService.getByUsername(username);

        // 检查要关注的用户是否存在
        User followUser = userMapper.selectById(userId);
        if (followUser == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查是否是自己
        if (currentUser.getId().equals(userId)) {
            throw new BusinessException("不能关注自己");
        }

        // 检查是否已经关注
        if (hasFollowed(currentUser.getId(), userId)) {
            throw new BusinessException("已经关注过该用户");
        }

        // 创建关注关系
        Friendship friendship = new Friendship();
        friendship.setUserId(currentUser.getId());
        friendship.setFriendId(userId);
        save(friendship);
    }

    @Override
    @Transactional
    public void deleteFriend(Long userId) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User currentUser = userService.getByUsername(username);

        // 删除关注关系
        LambdaQueryWrapper<Friendship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Friendship::getUserId, currentUser.getId())
                .eq(Friendship::getFriendId, userId);
        remove(wrapper);
    }

    @Override
    public boolean hasFollowed(Long userId, Long followId) {
        LambdaQueryWrapper<Friendship> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Friendship::getUserId, userId)
                .eq(Friendship::getFriendId, followId);
        return count(wrapper) > 0;
    }
} 